package graph_viewer.factory;

import java.util.*;

import graph_viewer.app_exception.*;
import graph_viewer.structure.*;
import graph_viewer.structure.builder.*;
import graph_viewer.structure.clustering.*;
import graph_viewer.util.*;

/**
	@since 2004_05
*/
public class  Graph_Cluster_Strategy_Factory{
	final public int 
		CREATE_STRATEGY	= 1,
		CLOSE_STRATEGY	= -1,
		NON_STRATEGY		= 0;

	public Graph_Cluster_Strategy create( Node node ){		
		int strategy	= find_strategy( node );

		/*if ( ! Structure_Util.is_parent_of_leaf_clusters( node ) ){
			throw new App_Exception( "Try to do cluster operation on a node that 's not a parent of leaf clusters!" );	 
		}*/

		if (  strategy == CLOSE_STRATEGY ){
			Debug.println( "CLOSING_CLUSTER_Strategy is created for " + node , 26 );
			return new Close_Cluster_Strategy();
		}  else if (  strategy == CREATE_STRATEGY ){
			Debug.println( "CREATE_PSEUDO_CLUSTER_STRATEGY is created for " + node, 26 );
			return new Create_Pseudo_Cluster_Strategy();
		} else if ( strategy == NON_STRATEGY  ){
			Debug.println( "Non_Cluster_Strategy is created for " + node , 26 );
			return new Non_Cluster_Strategy();
		} else {
			throw new App_Exception( "Invalid clustering strategy request!" );	 
		}
	}
	
	private int find_strategy( Node node ){
		ArrayList children = node.get_children();				
		
		int children_size	= children.size();
		int psuedo_children_size	= 0;
		int relevant_chidlren_size	= 0;

		for ( Iterator _i=children.iterator(); _i.hasNext() ; ){
			Node child	= (Node)_i.next();
			
			if ( child.get_is_psuedo() ){
				psuedo_children_size++;
			}else if ( !child.is_irrelevant() ){ // if a psuedo node is automatically irrelevant. 
				relevant_chidlren_size++;		
			}
		}
		
		int non_psuedo_children_size	= children_size - psuedo_children_size;

		Debug.println( "\t" + node 
			+ ", children_size: " + children_size
			+ ", psuedo_children_size: " + psuedo_children_size 
			+ ", relevant_chidlren_size: " + relevant_chidlren_size
			+ ", non_psuedo_children_size: " + non_psuedo_children_size
			, 25 );
		
		if ( relevant_chidlren_size  >  non_psuedo_children_size ){
			throw new App_Exception( "Wrong relevant_chidlren_size!" );	 
		}else if ( relevant_chidlren_size == 0 ){
			return CLOSE_STRATEGY;
		}else if ( relevant_chidlren_size  ==  non_psuedo_children_size ){
			return NON_STRATEGY;
		}else {
			return CREATE_STRATEGY;
		}
		
	}
}